package com.ternnetwork.oa.service.impl.note;

import com.ternnetwork.commons.model.http.BaseResponse;
import com.ternnetwork.core.accesscontroll.entity.User;
import com.ternnetwork.core.accesscontroll.service.UserService;
import com.ternnetwork.oa.dto.note.NoteCategoryDto;
import com.ternnetwork.oa.entity.note.NoteCategory;
import com.ternnetwork.oa.enums.messages.NoteCategoryMessages;
import com.ternnetwork.oa.repository.note.NoteCategoryRepository;
import com.ternnetwork.oa.repository.note.NoteRepository;
import com.ternnetwork.oa.service.note.NoteCategoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Optional;

@Service
public class NoteCategoryServiceImpl implements NoteCategoryService {

    @Autowired
    private NoteCategoryRepository noteCategoryRepository;
    @Autowired
    private UserService userService;
    @Autowired
    private NoteRepository noteRepository;

    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
    public BaseResponse add(NoteCategoryDto dto, String username){

        BaseResponse  baseResponse=checkProperties(dto);

        if(baseResponse.getStatus().intValue()==0) {

            return baseResponse;
        }

        User loginUser=userService.findByName(username);

        long totalCount=noteCategoryRepository.getCountByNameAndParentId(loginUser.getId(),dto.getName(),dto.getParentId());

        if(totalCount>0L) {
            baseResponse.setFailed(NoteCategoryMessages.FAILED_MESSAGE_NAME_CAN_NOT_BE_DUPLICATE.getName());
            return baseResponse;
        }

        NoteCategory noteCategory=new NoteCategory();

        noteCategory.setName(dto.getName());
        noteCategory.setParentId(dto.getParentId());
        noteCategory.setCreatedById(loginUser.getId());

        noteCategoryRepository.saveAndFlush(noteCategory);

        baseResponse.setSccucess();

        return baseResponse;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
    public BaseResponse update(NoteCategoryDto dto, String username){

        BaseResponse  baseResponse=checkProperties(dto);

        if(baseResponse.getStatus().intValue()==0) {

            return baseResponse;
        }

        Optional<NoteCategory> optional=noteCategoryRepository.findById(dto.getId());

        if(optional.equals(Optional.empty())){

            baseResponse.setFailedForObjectNotExist();

            return baseResponse;
        }
        NoteCategory noteCategory=optional.get();

        User loginUser=userService.findByName(username);

        if(noteCategory.getCreatedById()!=loginUser.getId()){

            baseResponse.setFailedForObjectNotBelongsToLoginUser();

            return baseResponse;
        }

        long totalCount=noteCategoryRepository.getCountByNameAndParentIdAndExcludeId(loginUser.getId(),dto.getName(),dto.getParentId(),dto.getParentId());

        if(totalCount>0L) {
            baseResponse.setFailed(NoteCategoryMessages.FAILED_MESSAGE_NAME_CAN_NOT_BE_DUPLICATE.getName());
            return baseResponse;
        }

        BeanUtils.copyProperties(dto,noteCategory);

        noteCategoryRepository.saveAndFlush(noteCategory);

        baseResponse.setSccucess();

        return baseResponse;
    }


    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
    public BaseResponse deleteById(Long id,String username){

        BaseResponse  baseResponse=new BaseResponse();

        Optional<NoteCategory> optional=noteCategoryRepository.findById(id);

        if(optional.equals(Optional.empty())){

            baseResponse.setFailedForObjectNotExist();

            return baseResponse;
        }
        NoteCategory noteCategory=optional.get();

        User loginUser=userService.findByName(username);

        if(noteCategory.getCreatedById()!=loginUser.getId()){

            baseResponse.setFailedForObjectNotBelongsToLoginUser();

            return baseResponse;
        }

        long totalCount=noteCategoryRepository.getCountByParentId(id);

        if(totalCount>0L) {
            baseResponse.setFailed(NoteCategoryMessages.FAILED_MESSAGE_CAN_NOT_DELETE_FOR_IT_HAS_CHILDREN.getName());
            return baseResponse;
        }

        noteRepository.updateByDeleteCategory(id);

        noteCategoryRepository.delete(noteCategory);

        baseResponse.setSccucess();

        return baseResponse;
    }


    public BaseResponse findAll(String username) {

        BaseResponse baseResponse = new BaseResponse();

        User loginUser=userService.findByName(username);

        List<NoteCategory> noteCategoryList=noteCategoryRepository.findAll(loginUser.getId());

        baseResponse.setSccucess(noteCategoryList);

        return baseResponse;

    }


    private BaseResponse checkProperties (NoteCategoryDto t) {

        BaseResponse  baseResponse=new BaseResponse();

        if(StringUtils.isEmpty(t.getName())) {

            baseResponse.setFailed(NoteCategoryMessages.FAILED_MESSAGE_NAME_CAN_NOT_BE_EMPTY.getName());

            return baseResponse;
        }

        baseResponse.setSccucess();

        return baseResponse;
    }
}
